//------------------------------------------------------------------------------
// The contents of this file are subject to the nopCommerce Public License Version 1.0 ("License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at  http://www.nopCommerce.com/License.aspx. 
// 
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. 
// See the License for the specific language governing rights and limitations under the License.
// 
// The Original Code is nopCommerce.
// The Initial Developer of the Original Code is NopSolutions.
// All Rights Reserved.
// 
// Contributor(s): _______. 
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using NopSolutions.NopCommerce.BusinessLogic;
using NopSolutions.NopCommerce.BusinessLogic.Model;
using NopSolutions.NopCommerce.Common;
using NopSolutions.NopCommerce.Common.Utils;
using NopSolutions.NopCommerce.BusinessLogic.Services;
using NopSolutions.NopCommerce.BusinessLogic.Infrastructure;

namespace NopSolutions.NopCommerce.Web.Modules
{
    public partial class SearchControl : BaseNopFrontendUserControl
    {
        private ISettingService _settingService;
        private ISearchLogService _searchLogService;
        private IProductService _productService;
        private ICategoryService _categoryService;
        private IManufacturerService _manufacturerService;
        private ICurrencyService _currencyService;

        protected override void OnInit(EventArgs e) {
            _settingService = IoC.Resolve<ISettingService>();
            _searchLogService = IoC.Resolve<ISearchLogService>();
            _productService = IoC.Resolve<IProductService>();
            _categoryService = IoC.Resolve<ICategoryService>();
            _manufacturerService = IoC.Resolve<IManufacturerService>();
            _currencyService = IoC.Resolve<ICurrencyService>();

            Load += new EventHandler(SearchControl_Load);
            PreRender += new EventHandler(SearchControl_PreRender);
            lvProducts.PagePropertiesChanging += new EventHandler<PagePropertiesChangingEventArgs>(lvProducts_OnPagePropertiesChanging);
            btnSearch.Click += new EventHandler(btnSearch_Click);
            cbAdvancedSearch.CheckedChanged += new EventHandler(cbAdvancedSearch_CheckedChanged);

            base.OnInit(e);
        }

        void cbAdvancedSearch_CheckedChanged(object sender, EventArgs e) {
            pnlAdvancedSearch.Visible = cbAdvancedSearch.Checked;
        }

        void SearchControl_Load(object sender, EventArgs e) {
            pnlFormInfo.Visible = false;
            pnlSearchResults.Visible = false;
            pnlPager.Visible = false;
            pnlAdvancedSearch.Visible = cbAdvancedSearch.Checked;

            if (!IsPostBack) {
                if (!String.IsNullOrEmpty(SearchTerms))
                    txtSearchTerm.Text = SearchTerms;

                BindData();
                BindCategories();
                BindManufacturers();
            }
        }

        void SearchControl_PreRender(object sender, EventArgs e) {
            this.txtSearchTerm.Attributes.Add("onkeydown", "if(event.which || event.keyCode){if ((event.which == 13) || (event.keyCode == 13)) {document.getElementById('" + btnSearch.ClientID + "').click();return false;}} else {return true}; ");
        }

        protected void BindData() {
            try {
                string keywords = txtSearchTerm.Text.Trim();
                pagerProducts.PageSize = _productService.SearchPageProductsPerPage;

                if (!String.IsNullOrEmpty(keywords)) {
                    int searchTermMinimumLength = _settingService.GetSettingValueInteger("Search.ProductSearchTermMinimumLength", 3);
                    if (keywords.Length < searchTermMinimumLength)
                        throw new NopException(string.Format(GetLocaleResourceString("Search.SearchTermMinimumLengthIsNCharacters"), searchTermMinimumLength));

                    bool advSearch = cbAdvancedSearch.Checked;
                    int categoryId = 0;
                    int manufacturerId = 0;
                    decimal? minPriceConverted = null;
                    decimal? maxPriceConverted = null;
                    bool searchInProductDescriptions = false;

                    if (advSearch) {
                        //categories
                        if (ddlCategories.Items.Count > 0)
                            categoryId = int.Parse(this.ddlCategories.SelectedItem.Value);

                        //manufacturers
                        if (ddlManufacturers.Items.Count > 0)
                            manufacturerId = int.Parse(this.ddlManufacturers.SelectedItem.Value);

                        //min price
                        decimal? minPrice = null;
                        try {
                            if (!string.IsNullOrEmpty(txtPriceFrom.Text.Trim())) {
                                minPrice = decimal.Parse(txtPriceFrom.Text.Trim());
                                if (minPrice.HasValue) {
                                    minPriceConverted = _currencyService.ConvertCurrency(minPrice.Value, NopContext.Current.WorkingCurrency, _currencyService.PrimaryStoreCurrency);
                                }
                            }
                        }
                        catch {
                            txtPriceFrom.Text = string.Empty;
                        }

                        //max price
                        decimal? maxPrice = null;
                        try {
                            if (!string.IsNullOrEmpty(txtPriceTo.Text.Trim())) {
                                maxPrice = decimal.Parse(txtPriceTo.Text.Trim());
                                if (maxPrice.HasValue) {
                                    maxPriceConverted = _currencyService.ConvertCurrency(maxPrice.Value, NopContext.Current.WorkingCurrency, _currencyService.PrimaryStoreCurrency);
                                }
                            }
                        }
                        catch {
                            txtPriceTo.Text = string.Empty;
                        }

                        //search in descriptions
                        searchInProductDescriptions = cbSearchInProductDescriptions.Checked;
                    }

                    int totalRecords = 0;
                    var products = _productService.GetAllProducts(categoryId,
                        manufacturerId, 0, null,
                        minPriceConverted, maxPriceConverted,
                        keywords, searchInProductDescriptions,
                        100, 0, new List<int>(), out totalRecords);

                    pnlSearchResults.Visible = products.Count > 0;

                    lvProducts.Visible = pnlSearchResults.Visible;
                    lvProducts.DataSource = products;
                    lvProducts.DataBind();

                    pnlPager.Visible = products.Count > pagerProducts.PageSize;
                    pnlFormInfo.Visible = !pnlSearchResults.Visible;
                    lblErrors.Text = GetLocaleResourceString("Search.NoResultsText");

                    int customerId = 0;
                    if (NopContext.Current.User != null)
                        customerId = NopContext.Current.User.CustomerId;

                    var searchLog = new SearchLog() {
                        SearchTerm = txtSearchTerm.Text.Trim(),
                        CustomerId = customerId,
                        CreatedOn = DateTime.UtcNow
                    };

                    _searchLogService.InsertSearchLog(searchLog);
                }
                else {
                    pnlSearchResults.Visible = false;
                    pnlPager.Visible = false;
                }
            }
            catch (Exception exc) {
                pnlSearchResults.Visible = false;
                pnlPager.Visible = false;
                pnlFormInfo.Visible = true;
                lblErrors.Text = Server.HtmlEncode(exc.Message);
            }
        }

        protected void BindCategories() {
            var categories = _categoryService.GetAllCategories();

            if (categories.Count > 0) {
                this.ddlCategories.Items.Clear();
                this.ddlCategories.Items.Add(new ListItem(GetLocaleResourceString("Search.AllCategories"), "0"));

                foreach (var category in categories) {
                    string catName = GetCategoryFullName(category);
                    ListItem item = new ListItem(catName, category.CategoryId.ToString());
                    this.ddlCategories.Items.Add(item);
                }

                this.ddlCategories.DataBind();
            }
            else {
                this.divCategories.Visible = false;
            }
        }

        protected string GetCategoryFullName(Category category) {
            string result = string.Empty;

            while (category != null && !category.Deleted) {
                if (String.IsNullOrEmpty(result)) {
                    result = category.LocalizedName;
                }
                else {
                    result = "--" + result;
                }
                category = category.ParentCategory;
            }
            return result;
        }

        protected void BindManufacturers() {
            var manufacturers = _manufacturerService.GetAllManufacturers();
            if (manufacturers.Count > 0) {
                this.ddlManufacturers.Items.Clear();
                this.ddlManufacturers.Items.Add(new ListItem(GetLocaleResourceString("Search.AllManufacturers"), "0"));

                foreach (var manufacturer in manufacturers) {
                    ListItem item2 = new ListItem(manufacturer.LocalizedName, manufacturer.ManufacturerId.ToString());
                    this.ddlManufacturers.Items.Add(item2);
                }
            }
            else {
                this.divManufacturers.Visible = false;
            }
        }

        protected void lvProducts_OnPagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e) {
            this.pagerProducts.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
            BindData();
        }

        protected void btnSearch_Click(object sender, EventArgs e) {
            BindData();
        }

        public string SearchTerms {
            get {
                return CommonHelper.QueryString("SearchTerms");
            }
        }
    }
}